package my.containertest;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.TreeMap;
import java.util.TreeSet;
class Z implements Comparable<Z>{
	int i;
	Z(int s){i=s;}
	@Override
	public String toString(){return Integer.toString(i)+'@'+super.toString();}
	@Override
	public boolean equals(Object obj){
		return ((Z)obj).i == i;
	}
	@Override
	public int compareTo(Z o) {
		// TODO Auto-generated method stub
		return i-o.i;
	}
};
class Zz extends Z{
	Zz(int s){
		super(s*2);
	}
	@Override
	public String toString(){return Integer.toString(i);}
};
class Y{
	int i;
	Y(int s){i=-s;}
	public String toString(){return Integer.toString(i);}
	public int hashCode(){
		return (i^(i>>>1))%101;
	}
	public boolean equals(Object obj){
		return ((Y)obj).i==i;
	}
};

interface Dbg{
 <E, F> E p(F f);
}

public class ContainerTest {

/**
 * @param <E>
 * @param args
 */
static <E> void printall(Collection<E> co,Dbg dbg){
	/*
	Iterator<E> i=co.iterator();
	while(i.hasNext()){
		System.out.print(dbg.p(i.next())+" ");
	}*/
	for(E i : co)
		System.out.println(dbg.p(i)+" ");
	System.out.println();
}
static <E> void out(E  x){  
	System.out.println(x);
}
public static void main(String[] args) {
	// TODO Auto-generated method stub
	
	/*ArrayList Test*/
	out("ArrayList");
	ArrayList<Z> al=new ArrayList<Z>();
	for(int i=0;i<10;i++)al.add(new Z(i));
	System.out.println(al);
	for(int i=0;i<10;i++)al.add(new Zz(i));
	System.out.println(al);
	al.add(1,new Zz(100));//add a new elem. at index 1
	System.out.println(al);
	//al.add(100,new Z(0)); //IndexOutofBoundsException
	System.out.println(al.contains(new Z(2)));
	printall(al,
			new Dbg(){
				@SuppressWarnings("unchecked")
				@Override
				public <E, F> E p(F f) {
					// TODO Auto-generated method stub
					return (E) f;
				}
			}
			);
	System.out.println((Collections.max(al)));
	
	//LinkedList
	out("");
	out("LinkedList");
	LinkedList<Z> ll = new LinkedList<Z>();
	for(int i=0;i<10;i++)ll.push(new Zz(i));
	out(ll);
	ll.add(new Zz(-1));out("after add");
	out(ll);
	ll.offer(new Zz(-2));out("after offer");
	out(ll);
	ll.poll();out("after poll");
	out(ll);
	
	//TreeSet
	out("\nTreeSet");
	TreeSet<Z> ts = new TreeSet<Z>();
	for(int i=0;i<10;i++)ts.add(new Z(i));
	out(ts);
	out(ts.subSet(new Z(3), new Z(6)));
	/*
	TreeSet<Y> ts2  = new TreeSet<Y>();
	for(int i=0;i<10;i++)ts2.add(new Y(i));
	out(ts2);
	//Error! not comparable.
	*/
	
	//Hashset
	out("\nHashSet");
	HashSet<Z> hs=new HashSet<Z>();
	for(int i=0;i<10;i++)hs.add(new Z(i));
	out(hs);
	hs.remove(new Z(5));
	out("failed to remove if hashCode() isn't implemented");
	out(hs);
	HashSet<Y> hs2  = new HashSet<Y>();
	for(int i=0;i<10;i++)hs2.add(new Y(i));
	out(hs2);
	hs2.add(new Y(5));
	printall(hs2,
			new Dbg(){

				@SuppressWarnings("unchecked")
				@Override
				public <E, F> E p(F f) {
					// TODO Auto-generated method stub
					Integer ret=f.hashCode();
					return (E)ret;
				}
				
			}
			);
	
	printall(hs2,
			new Dbg(){

				@SuppressWarnings("unchecked")
				@Override
				public <E, F> E p(F f) {
					// TODO Auto-generated method stub
					Boolean ret=f.equals(new Y(0));
					return (E)ret;
				}
				
			}
			);

	out(hs2.remove(new Y(0)));
	out(hs2);
	
	//HashMap
	out("\nHashMap");
	HashMap<Y,Z> hm =new HashMap<Y,Z>();
	for(int i=0;i<10;i++)hm.put(new Y(i), new Z(i));
	out(hm);
	out(hm.get(new Y(5)));
	out(hm.keySet());
	hm.remove(new Y(5));
	out(hm);
	out(hm.values());
	
	//TreeMap
	out("\nTreeMap");
	TreeMap<Z,Y> tm=new TreeMap<Z,Y>();
	for(int i=0;i<10;i++)tm.put(new Z(i), new Y(i));
	out(tm);
	out(tm.get(new Z(5)));
	out(tm.ceilingKey(new Z(5)));
	out(tm.ceilingEntry(new Z(5)));
	out(tm.headMap(new Z(5)));
	out(tm.subMap(new Z(3), new Z(7)));
	
}

}